#pragma once
#include "Comm.h"
#include "Atom.h"
#include "Thread.h"

namespace COMM
{
	template<class T>
	class Singleton
	{
	protected:
		static T* volatile	inst;
		static volatile int	state;
	public:

		// lock free version.
		static T* Instance()
		{
			if(NULL == inst)
			{
				int state_current = Atom::Exchange(state,1);
				if(0 == state_current)
				{
					// state == 1 now.
					T* inst_new = new T();
					MYLIB_ASSERT_SILENCE(NULL!=inst_new);
					MYLIB_MEMORY_FENCE; 
					MYLIB_ASSERT_SILENCE(NULL==Atom::CompareExchangePointer((void* volatile&)inst,inst_new,NULL));
				}
				else
				{
					MYLIB_ASSERT_SILENCE(1==state_current);
					// creating instance now...
					// just waiting for creating finish.
					while(NULL == inst)
					{
						Thread::Sleep(1);
					}
				}

			}
			
			return inst;
		}

	};
	template<class T> T* volatile	Singleton<T>::inst = NULL;
	template<class T> volatile int	Singleton<T>::state = 0;
}


